%{

#include "member_type.h"
#include "record.h"
#include <cstdio>
#include <cstring>
#include <cctype>

int yylex();
void yyerror(const char* error);

%}

%union {
	char* string_;
	struct MemberType* type_;
	struct Record* record_;
	struct Member* member_;
}

%token <type_> PRIMITIVE_TYPE
%token <string_> IDENTIFIER
%token RECORD
%token SEMICOLON
%token OBRACE CBRACE

%type <record_> record record_content
%type <member_> member
%type <type_> type

%%
%start file;

file:
	record {
		char* name = (char*)malloc(strlen($1->name())+20);

		// header
		strcpy(name, "record-");
		strcat(name, $1->name());
		strcat(name, ".h");

		for (int i = 0; name[i] != 0; ++i)
			name[i] = tolower(name[i]);

		FILE* f = fopen(name, "wt");
		if (f == NULL)
			YYABORT;
		$1->generate_header(f);
		fclose(f);

		free(name);
	};

record:
	RECORD IDENTIFIER OBRACE record_content CBRACE {
		$$ = $4;
		$$->set_name($2);
	};

record_content:
	record_content member {
		$$ = $1;
		$$->add($2);
	}
	|
	member {
		$$ = new Record();
		$$->add($1);
	};

member:
	type IDENTIFIER SEMICOLON {
		$$ = new Member;
		$$->set_type($1);
		$$->set_name($2);
	};

type: PRIMITIVE_TYPE

%%

void yyerror(const char* error) {
	fprintf(stderr, "Error: %s\n", error);
}

int main() {
	yyparse();
	return 0;
}
